package service

import (
	"gitee.com/dayu1985/can_api/service/base"
	"gitee.com/dayu1985/can_api/models/sqlbean"
	"gitee.com/dayu1985/can_api/errors"
	"gitee.com/dayu1985/framework/net/web"
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"gitee.com/dayu1985/can_api/models/views"
	"hub.hddznet.com/app/framework/tools"
	"strings"
)

// 登录
func (this *UserService) Login(name, pwd string) (interface{}, error) {
	user := new(sqlbean.User)
	_, err := this.E.Where("account = ?", name).Get(user)
	if err != nil {
		return nil, errors.XormSearchErr(err.Error())
	}
	if user.ID == nil {
		return nil, errors.UserNotFoundErr()
	}

	var encryptStr string
	if user.Salt != nil && len(*user.Salt) > 0 {
		pwd := web.DecBase64(pwd)
		salt := *user.Salt
		var buf bytes.Buffer
		buf.WriteString(pwd)

		hash := sha256.New()

		hash.Write([]byte(buf.String()))
		hash.Write([]byte("$"))
		hash.Write([]byte(salt))

		encryptStr = hex.EncodeToString(hash.Sum(nil))
	} else {
		//兼容未加密数据
		encryptStr = web.DecBase64(pwd)
	}

	if encryptStr != ( *user.Password ) {
		return nil, errors.UserPwdErr()
	}
	return user, nil
}

// 用户通讯录
func (this *UserService) UserList() (interface{}, error) {
	// 所有用户数据
	users := make([]views.UserView, 0)
	err := this.E.Table(sqlbean.User{}).Find(&users)
	if err != nil {
		return nil, errors.XormSearchErr(err.Error())
	}

	// 部门列表
	groups := make([]sqlbean.Group, 0)
	err = this.E.Find(&groups)
	if err != nil {
		return nil, errors.XormSearchErr(err.Error())
	}

	// 返回数据
	type group struct {
		G          sqlbean.Group    `json:"-"`
		Department string           `json:"department"`
		User       []views.UserView `json:"user"`
	}
	dict := map[string]group{}

	// 对于没有对应的部门信息的用户处理
	if len(groups) == 0 {
		return group{Department: "未分配", User: users}, nil
	}

	for _, o := range groups {
		if o.ID == nil || o.Name == nil {
			continue
		}
		if _, ok := dict[*o.ID]; !ok {
			dict[*o.ID] = group{G: o, Department: *o.Name, User: make([]views.UserView, 0)}
		}
	}
	dict["weifenpei"] = group{Department: "未分配", User: make([]views.UserView, 0)}

	for _, u := range users {
		if u.Group == "" {
			u.Group = "weifenpei"
		}
		gp := dict[u.Group]
		gp.User = append(gp.User, u)
		dict[u.Group] = gp
	}
	result := make([]group, 0)
	for k := range dict {
		if len(dict[k].User) != 0 {
			result = append(result, dict[k])
		}
	}
	return result, nil
}

func (this *UserService) GroupUsers(code, regex string) (interface{}, error) {
	// 部门列表
	groups := make([]sqlbean.Group, 0)
	err := this.E.Find(&groups)
	if err != nil {
		return nil, errors.XormSearchErr(err.Error())
	}

	codes := make([]string, 0)
	groupIds := make([]string, 0)
	// 获取顶级公司
	for _, g := range groups {
		if g.Code == nil {
			continue
		}
		if code == *g.Code {
			codes = append(codes, *g.Code)
			groupIds = append(groupIds, *g.ID)
		}
	}
	// 若顶级公司不存在了，直接返回空
	if len(codes) == 0 {
		return nil, nil
	}

	// 若顶级公司不存在了，直接返回空,遍历多次，找到所有的下属公司
	for i := 0; i < 4; i ++ {
		for _, g := range groups {
			if g.Code == nil || g.Parent == nil {
				continue
			}

			if tools.StrContains(codes, *g.Parent) && !tools.StrContains(codes, *g.Code) {
				codes = append(codes, *g.Code)
				groupIds = append(groupIds, *g.ID)
			}
		}
	}

	users := make([]struct{
		ID        string `json:"_id" xorm:"pk varchar(50) not null '_id'"` //ID
		Name      string `json:"name" xorm:"VARCHAR(255)"`
		Account      string `json:"account" xorm:"VARCHAR(255)"`
	}, 0)
	if strings.Trim(regex, " ") == "" {
		this.E.Table(new(sqlbean.User)).In("group", groupIds).OrderBy("account").Find(&users)
	}else{
		this.E.Table(new(sqlbean.User)).Where("name like ?","%"+regex+"%").In("group", groupIds).OrderBy("account").Find(&users)
	}

	return users, nil
}

func (this *UserService) Users(ids ... string) ([]views.UserView, error) {
	users := make([]views.UserView, 0)
	err := this.E.Table(sqlbean.User{}).In("_id", ids).Find(&users)
	if err != nil {
		return nil, errors.XormSearchErr(err.Error())
	}
	return users, nil
}

// 上下班更新方法 state 1 上班，state 0 下班
func (this *UserService) Sign(state int, id string) (error) {
	user := new(sqlbean.User)
	_, err := this.E.Table(sqlbean.User{}).Exec("update "+this.E.TableInfo(user).Name+" set state = ? where _id = ?", state, id)
	if err != nil {
		return errors.XormUpdateErr(err.Error())
	}

	sta := new(sqlbean.UserState)
	sta.User = &id
	sta.State = &state
	sta.App = applicationView.ID
	_, err = this.E.Insert(sta)
	if err != nil {
		return errors.XormInsertErr(err.Error())
	}
	return nil
}

type UserService struct {
	E *base.Service
}

var userService *UserService

func NewUserService() *UserService {
	if userService == nil {
		u := new(UserService)
		base.RegisterService(u)
		userService = u
	}
	return userService
}

func init() {

}
